package com.fancy.music.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fancy.common.dto.PageResult;
import com.fancy.common.dto.SongBasicInfo;
import com.fancy.music.dto.GlobalSearchResultDTO;
import com.fancy.music.dto.SongDetailDTO;
import com.fancy.music.entity.Song;
import com.fancy.music.entity.SongPlayStats;
import com.fancy.music.mapper.SongMapper;
import com.fancy.music.mapper.SongPlayStatsMapper;
import com.fancy.music.service.AlbumService;
import com.fancy.music.service.ArtistService;
import com.fancy.music.service.SongService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import lombok.var;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Slf4j
@Service
@RequiredArgsConstructor
public class SongServiceImpl implements SongService {

    private final SongMapper songMapper;
    private final SongPlayStatsMapper songPlayStatsMapper;
    private final ArtistService artistService;
    private final AlbumService albumService;

    @Override
    public Song getSongDetail(Long songId) {
        return songMapper.selectById(songId);
    }

    @Override
    public SongDetailDTO getSongDetailWithInfo(Long songId) {
        Song song = songMapper.selectById(songId);
        if (song == null) {
            return null;
        }

        return convertToSongDetailDTO(song);
    }

    @Override
    public PageResult<Song> searchSongs(String keyword, String genre, String language, Integer isVip, int page, int size) {
        Page<Song> pageRequest = new Page<>(page, size);
        QueryWrapper<Song> queryWrapper = new QueryWrapper<>();

        if (StringUtils.hasText(keyword)) {
            queryWrapper.and(wrapper ->
                wrapper.like("song_name", keyword)
                       .or()
                       .exists("SELECT 1 FROM t_artist a WHERE a.artist_id = t_song.artist_id AND a.artist_name LIKE CONCAT('%', '" + keyword + "', '%')")
            );
        }

        if (StringUtils.hasText(genre)) {
            queryWrapper.eq("genre", genre);
        }

        if (StringUtils.hasText(language)) {
            queryWrapper.eq("language", language);
        }

        if (isVip != null) {
            queryWrapper.eq("is_vip", isVip);
        }

        queryWrapper.eq("status", 1)
                   .eq("audit_status", 1)
                   .orderByDesc("create_time");

        Page<Song> pageResult = songMapper.selectPage(pageRequest, queryWrapper);
        return new PageResult<>(pageResult.getRecords(), pageResult.getTotal());
    }

    @Override
    public List<Song> getHotSongs(Integer limit) {
        return songMapper.selectHotSongs(limit != null ? limit : 10);
    }

    @Override
    public List<Song> getNewSongs(Integer limit) {
        return songMapper.selectNewSongs(limit != null ? limit : 10);
    }

    @Override
    public List<Song> getSongsByArtistId(Long artistId) {
        return songMapper.selectByArtistId(artistId);
    }

    @Override
    public List<Song> getSongsByAlbumId(Long albumId) {
        return songMapper.selectByAlbumId(albumId);
    }

    @Override
    @Transactional
    public String playSong(Long songId, Long userId) {
        // 检查歌曲是否存在且可播放
        Song song = songMapper.selectById(songId);
        if (song == null || song.getStatus() != 1 || song.getAuditStatus() != 1) {
            throw new RuntimeException("歌曲不存在或不可播放");
        }

        // 检查VIP权限 (这里可以通过Feign调用用户服务检查)
        if (song.getIsVip() == 1) {
            // TODO: 调用用户服务检查VIP状态
            // boolean isVip = userServiceClient.checkVipStatus(userId);
            // if (!isVip) {
            //     throw new RuntimeException("该歌曲需要VIP权限");
            // }
            log.warn("VIP权限检查未实现，歌曲ID: {}, 用户ID: {}", songId, userId);
        }

        // 记录播放统计
        recordPlayStats(songId);

        // 返回播放URL
        return song.getFileUrl();
    }

    @Override
    public SongBasicInfo getSongBasicInfo(Long songId) {
        Song song = songMapper.selectById(songId);
        if (song == null) {
            return null;
        }

        SongBasicInfo info = new SongBasicInfo();
        info.setSongId(song.getSongId());
        info.setSongName(song.getSongName());
        info.setArtistId(song.getArtistId());
        info.setAlbumId(song.getAlbumId());
        info.setDuration(song.getDuration());
        info.setCoverUrl(song.getCoverUrl());
        info.setGenre(song.getGenre());
        info.setIsVip(song.getIsVip() == 1);

        // 获取歌手名称
        try {
            if (song.getArtistId() != null) {
                var artistInfo = artistService.getArtistBasicInfo(song.getArtistId());
                info.setArtistName(artistInfo != null ? artistInfo.getArtistName() : "未知艺术家");
            } else {
                info.setArtistName("未知艺术家");
            }
        } catch (Exception e) {
            log.warn("获取歌手信息失败, artistId: {}", song.getArtistId(), e);
            info.setArtistName("未知艺术家");
        }

        // 获取专辑名称
        try {
            if (song.getAlbumId() != null) {
                var albumInfo = albumService.getAlbumBasicInfo(song.getAlbumId());
                info.setAlbumName(albumInfo != null ? albumInfo.getAlbumName() : "未知专辑");
            } else {
                info.setAlbumName("未知专辑");
            }
        } catch (Exception e) {
            log.warn("获取专辑信息失败, albumId: {}", song.getAlbumId(), e);
            info.setAlbumName("未知专辑");
        }

        return info;
    }

    @Override
    public List<SongBasicInfo> getSongBasicInfoBatch(List<Long> songIds) {
        if (songIds == null || songIds.isEmpty()) {
            return Collections.emptyList();
        }

        List<Song> songs = songMapper.selectBatchIds(songIds);
        return songs.stream()
                .map(this::convertToBasicInfo)
                .collect(Collectors.toList());
    }

    @Override
    public boolean isVipSong(Long songId) {
        Song song = songMapper.selectById(songId);
        return song != null && song.getIsVip() == 1;
    }

    @Override
    @Transactional
    public void recordPlayStats(Long songId) {
        try {
            // 检查播放统计记录是否存在
            SongPlayStats stats = songPlayStatsMapper.selectBySongId(songId);
            if (stats == null) {
                // 创建新的统计记录
                stats = new SongPlayStats();
                stats.setSongId(songId);
                stats.setPlayCount(1L);
                stats.setDailyPlayCount(1L);
                stats.setWeeklyPlayCount(1L);
                stats.setMonthlyPlayCount(1L);
                stats.setLastUpdateDate(new Date());
                stats.setUpdateTime(new Date());
                songPlayStatsMapper.insert(stats);
            } else {
                // 更新播放次数
                songPlayStatsMapper.incrementPlayCount(songId);
            }
        } catch (Exception e) {
            log.error("记录播放统���失败", e);
        }
    }

    @Override
    @Transactional
    public Long createSong(Song song) {
        try {
            song.setCreateTime(new Date());
            song.setUpdateTime(new Date());
            song.setStatus(1);
            song.setAuditStatus(0); // 待审核

            int result = songMapper.insert(song);

            if (result > 0) {
                // 初始化播放统计
                SongPlayStats stats = new SongPlayStats();
                stats.setSongId(song.getSongId());
                stats.setPlayCount(0L);
                stats.setDailyPlayCount(0L);
                stats.setWeeklyPlayCount(0L);
                stats.setMonthlyPlayCount(0L);
                stats.setLastUpdateDate(new Date());
                stats.setUpdateTime(new Date());
                songPlayStatsMapper.insert(stats);

                return song.getSongId();
            }

            return null;
        } catch (Exception e) {
            log.error("创建歌曲失败", e);
            return null;
        }
    }

    @Override
    @Transactional
    public boolean updateSong(Song song) {
        try {
            song.setUpdateTime(new Date());
            return songMapper.updateById(song) > 0;
        } catch (Exception e) {
            log.error("更新歌曲失败", e);
            return false;
        }
    }

    @Override
    @Transactional
    public boolean deleteSong(Long songId) {
        try {
            // 删除歌曲统计
            QueryWrapper<SongPlayStats> statsWrapper = new QueryWrapper<>();
            statsWrapper.eq("song_id", songId);
            songPlayStatsMapper.delete(statsWrapper);

            // 删除歌曲
            return songMapper.deleteById(songId) > 0;
        } catch (Exception e) {
            log.error("删除歌曲失败", e);
            return false;
        }
    }

    @Override
    @Transactional
    public boolean auditSong(Long songId, Integer auditStatus, String auditRemark) {
        try {
            Song song = new Song();
            song.setSongId(songId);
            song.setAuditStatus(auditStatus);
            song.setUpdateTime(new Date());

            return songMapper.updateById(song) > 0;
        } catch (Exception e) {
            log.error("审核歌曲失败", e);
            return false;
        }
    }

    @Override
    public List<Song> getRecommendedSongs(Long userId, Integer limit) {
        return songMapper.selectRecommendedSongs(userId, limit != null ? limit : 10);
    }

    @Override
    public List<SongDetailDTO> getNewSongsWithDetails(Integer limit) {
        List<Song> songs = songMapper.selectNewSongs(limit != null ? limit : 10);
        return songs.stream()
                .map(this::convertToSongDetailDTO)
                .collect(Collectors.toList());
    }

    @Override
    public List<SongDetailDTO> getHotSongsWithDetails(Integer limit) {
        List<Song> songs = songMapper.selectHotSongs(limit != null ? limit : 10);
        return songs.stream()
                .map(this::convertToSongDetailDTO)
                .collect(Collectors.toList());
    }

    @Override
    public PageResult<SongDetailDTO> searchSongsWithDetails(String keyword, String genre, String language, Integer isVip, int page, int size) {
        PageResult<Song> songPage = searchSongs(keyword, genre, language, isVip, page, size);
        List<SongDetailDTO> detailDTOs = songPage.getRecords().stream()
                .map(this::convertToSongDetailDTO)
                .collect(Collectors.toList());
        return new PageResult<>(detailDTOs, songPage.getTotal());
    }

    @Override
    public List<SongDetailDTO> getRecommendedSongsWithDetails(Long userId, Integer limit) {
        List<Song> songs = songMapper.selectRecommendedSongs(userId, limit != null ? limit : 10);
        return songs.stream()
                .map(this::convertToSongDetailDTO)
                .collect(Collectors.toList());
    }

    @Override
    public List<SongDetailDTO> getSongsByArtistIdWithDetails(Long artistId) {
        List<Song> songs = songMapper.selectByArtistId(artistId);
        return songs.stream()
                .map(this::convertToSongDetailDTO)
                .collect(Collectors.toList());
    }

    @Override
    public List<SongDetailDTO> getSongsByAlbumIdWithDetails(Long albumId) {
        List<Song> songs = songMapper.selectByAlbumId(albumId);
        return songs.stream()
                .map(this::convertToSongDetailDTO)
                .collect(Collectors.toList());
    }

    /**
     * 将Song实体转换为SongDetailDTO
     */
    private SongDetailDTO convertToSongDetailDTO(Song song) {
        SongDetailDTO dto = new SongDetailDTO();
        dto.setSongId(song.getSongId());
        dto.setSongName(song.getSongName());
        dto.setArtistId(song.getArtistId());
        dto.setAlbumId(song.getAlbumId());
        dto.setDuration(song.getDuration());
        dto.setFileUrl(song.getFileUrl());
        dto.setCoverUrl(song.getCoverUrl() != null ? song.getCoverUrl() : "/images/default_music_cover.png");
        dto.setLyricUrl(song.getLyricUrl());
        dto.setGenre(song.getGenre());
        dto.setLanguage(song.getLanguage());
        dto.setReleaseDate(song.getReleaseDate());
        dto.setFileSize(song.getFileSize());
        dto.setBitRate(song.getBitRate());
        dto.setFormat(song.getFormat());
        dto.setIsVip(song.getIsVip());
        dto.setAuditStatus(song.getAuditStatus());
        dto.setStatus(song.getStatus());
        dto.setCreateTime(song.getCreateTime());
        dto.setUpdateTime(song.getUpdateTime());

        // 获取歌手名称
        try {
            if (song.getArtistId() != null) {
                var artistInfo = artistService.getArtistBasicInfo(song.getArtistId());
                dto.setArtistName(artistInfo != null ? artistInfo.getArtistName() : "未知艺术家");
            } else {
                dto.setArtistName("未知艺术家");
            }
        } catch (Exception e) {
            log.warn("获取歌手信息失败, artistId: {}", song.getArtistId(), e);
            dto.setArtistName("未知艺术家");
        }

        // 获取专辑名称
        try {
            if (song.getAlbumId() != null) {
                var albumInfo = albumService.getAlbumBasicInfo(song.getAlbumId());
                dto.setAlbumName(albumInfo != null ? albumInfo.getAlbumName() : "未知专辑");
            } else {
                dto.setAlbumName("未知专辑");
            }
        } catch (Exception e) {
            log.warn("获取专辑信息失败, albumId: {}", song.getAlbumId(), e);
            dto.setAlbumName("未知专辑");
        }

        // 获取播放次数
        try {
            SongPlayStats stats = songPlayStatsMapper.selectBySongId(song.getSongId());
            dto.setPlayCount(stats != null ? stats.getPlayCount() : 0L);
        } catch (Exception e) {
            log.warn("获取播放统计失败, songId: {}", song.getSongId(), e);
            dto.setPlayCount(0L);
        }

        // 默认收藏状态为false，实际应用中需要根据用户ID查询
        dto.setIsCollected(false);

        return dto;
    }

    private SongBasicInfo convertToBasicInfo(Song song) {
        SongBasicInfo info = new SongBasicInfo();
        info.setSongId(song.getSongId());
        info.setSongName(song.getSongName());
        info.setArtistId(song.getArtistId());
        info.setAlbumId(song.getAlbumId());
        info.setDuration(song.getDuration());
        info.setCoverUrl(song.getCoverUrl());
        info.setGenre(song.getGenre());
        info.setIsVip(song.getIsVip() == 1);

        // 获取歌手名称
        try {
            if (song.getArtistId() != null) {
                var artistInfo = artistService.getArtistBasicInfo(song.getArtistId());
                info.setArtistName(artistInfo != null ? artistInfo.getArtistName() : "未知艺术家");
            } else {
                info.setArtistName("未知艺术家");
            }
        } catch (Exception e) {
            log.warn("获取歌手信息失败, artistId: {}", song.getArtistId(), e);
            info.setArtistName("未知艺术家");
        }

        // 获取专辑名称
        try {
            if (song.getAlbumId() != null) {
                var albumInfo = albumService.getAlbumBasicInfo(song.getAlbumId());
                info.setAlbumName(albumInfo != null ? albumInfo.getAlbumName() : "未知专辑");
            } else {
                info.setAlbumName("未知专辑");
            }
        } catch (Exception e) {
            log.warn("获取专辑信息失败, albumId: {}", song.getAlbumId(), e);
            info.setAlbumName("未知专辑");
        }

        return info;
    }

    @Override
    public List<String> getAllSongGenres() {
        try {
            QueryWrapper<Song> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("status", 1)
                       .eq("audit_status", 1)
                       .isNotNull("genre")
                       .ne("genre", "");

            List<Song> songs = songMapper.selectList(queryWrapper);

            List<String> genres = songs.stream()
                    .filter(song -> song.getGenre() != null && !song.getGenre().trim().isEmpty())
                    .flatMap(song -> {
                        String[] genreArray = song.getGenre().split("[,，]");
                        return java.util.Arrays.stream(genreArray)
                                .map(String::trim)
                                .filter(genre -> !genre.isEmpty());
                    })
                    .distinct()
                    .sorted()
                    .collect(Collectors.toList());

            // 在最前面添加"全部"选项
            List<String> result = new ArrayList<>();
            result.add("全部");
            result.addAll(genres);
            return result;
        } catch (Exception e) {
            log.error("获取歌曲音乐风格失败", e);
            List<String> fallbackResult = new ArrayList<>();
            fallbackResult.add("全部");
            return fallbackResult;
        }
    }

    @Override
    public List<Song> getSongsByGenreMatch(String genre, Integer limit) {
        try {
            QueryWrapper<Song> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("status", 1)
                       .eq("audit_status", 1);

            // 如果传入的是"全部"，则不添加音乐风格过滤条件
            if (!"全部".equals(genre)) {
                queryWrapper.and(wrapper -> wrapper.like("genre", genre));
            }

            queryWrapper.orderByDesc("create_time");

            if (limit != null && limit > 0) {
                queryWrapper.last("LIMIT " + limit);
            }

            return songMapper.selectList(queryWrapper);
        } catch (Exception e) {
            log.error("根据音乐风格获取歌曲失败", e);
            return Collections.emptyList();
        }
    }

    @Override
    public List<SongDetailDTO> getSongsByGenreMatchWithDetails(String genre, Integer limit) {
        List<Song> songs = getSongsByGenreMatch(genre, limit);
        return songs.stream()
                .map(this::convertToSongDetailDTO)
                .collect(Collectors.toList());
    }

    @Override
    public GlobalSearchResultDTO globalSearch(String keyword, Integer limit) {
        try {
            if (!StringUtils.hasText(keyword)) {
                return new GlobalSearchResultDTO();
            }

            // 设置默认限制数量
            int searchLimit = limit != null && limit > 0 ? limit : 10;

            GlobalSearchResultDTO result = new GlobalSearchResultDTO();
            result.setKeyword(keyword);

            // 搜索歌曲
            List<SongDetailDTO> songs = searchSongsForGlobal(keyword, searchLimit);
            result.setSongs(songs);
            result.setSongCount((long) songs.size());

            // 搜索歌手
            List<com.fancy.music.dto.ArtistDetailDTO> artists = searchArtistsForGlobal(keyword, searchLimit);
            result.setArtists(artists);
            result.setArtistCount((long) artists.size());

            // 搜索专辑
            List<com.fancy.music.dto.AlbumDetailDTO> albums = searchAlbumsForGlobal(keyword, searchLimit);
            result.setAlbums(albums);
            result.setAlbumCount((long) albums.size());

            // 计算总数
            result.calculateTotalCount();

            return result;
        } catch (Exception e) {
            log.error("全局搜索失败，关键词: {}", keyword, e);
            GlobalSearchResultDTO fallbackResult = new GlobalSearchResultDTO();
            fallbackResult.setKeyword(keyword);
            return fallbackResult;
        }
    }

    /**
     * 搜索歌曲（用于全局搜索）
     */
    private List<SongDetailDTO> searchSongsForGlobal(String keyword, int limit) {
        try {
            QueryWrapper<Song> queryWrapper = new QueryWrapper<>();
            queryWrapper.and(wrapper ->
                wrapper.like("song_name", keyword)
                       .or()
                       .exists("SELECT 1 FROM t_artist a WHERE a.artist_id = t_song.artist_id AND a.artist_name LIKE CONCAT('%', '" + keyword + "', '%')")
                       .or()
                       .exists("SELECT 1 FROM t_album al WHERE al.album_id = t_song.album_id AND al.album_name LIKE CONCAT('%', '" + keyword + "', '%')")
            );

            queryWrapper.eq("status", 1)
                       .eq("audit_status", 1)
                       .orderByDesc("create_time")
                       .last("LIMIT " + limit);

            List<Song> songs = songMapper.selectList(queryWrapper);
            return songs.stream()
                    .map(this::convertToSongDetailDTO)
                    .collect(Collectors.toList());
        } catch (Exception e) {
            log.error("搜索歌曲失败", e);
            return Collections.emptyList();
        }
    }

    /**
     * 搜索歌手（用于全局搜索）
     */
    private List<com.fancy.music.dto.ArtistDetailDTO> searchArtistsForGlobal(String keyword, int limit) {
        try {
            return artistService.searchArtistsWithDetails(keyword, null, null, null, 1, limit).getRecords();
        } catch (Exception e) {
            log.error("搜索歌手失败", e);
            return Collections.emptyList();
        }
    }

    /**
     * 搜��专辑（用于全���搜索）
     */
    private List<com.fancy.music.dto.AlbumDetailDTO> searchAlbumsForGlobal(String keyword, int limit) {
        try {
            return albumService.searchAlbumsWithDetails(keyword, null, null, 1, limit).getRecords();
        } catch (Exception e) {
            log.error("搜索专辑失败", e);
            return Collections.emptyList();
        }
    }
}
